package com.dn;

import com.aliyun.alidns20150109.Client;
import com.aliyun.alidns20150109.models.AddDomainRecordResponse;
import com.aliyun.alidns20150109.models.DescribeDomainRecordsResponse;
import com.aliyun.alidns20150109.models.DescribeDomainRecordsResponseBody;
import com.aliyun.alidns20150109.models.UpdateDomainRecordResponse;
import com.aliyun.tea.TeaException;
import com.dn.config.ClientBuilder;
import com.dn.config.IPv6Address;
import com.dn.ddns.ResolutionDNS;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Stack;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;


/**
 * @program: ddns
 * @description: 启动类
 * @author: DN
 * @create: 2021-04-04 18:52
 **/
public class MyStart {


    /**
     * ACCESS_KEY_ID : 阿里云账号的 AccessKey ID
     * SECRET : 阿里云账号的 AccessKey Secret
     * END_POINT : 你要请求的服务地址,可根据自己所处地域就近选择
     * 各服务可查询地址 : https://next.api.aliyun.com/api/
     */
    private static final String ACCESS_KEY_ID = "";
    private static final String SECRET = "";
    private static final String END_POINT = "alidns.cn-shenzhen.aliyuncs.com";

    private static final String DOMAIN_NAME = ""; // 你需要解析的阿里云域名

    private static Stack<String> ipStack = new Stack<>(); // 创建一个变量栈,用于ip变化时进行操作
    public static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH时mm分ss秒"); // 日期格式化
    // 请求角色
    private static Client client;
    // 本机IPv6地址
    private static String ip = "";

    static {
        ipStack.push("");
        if (client == null) {
            try {
                client = ClientBuilder.createClient(ACCESS_KEY_ID, SECRET, END_POINT);
            } catch (Exception e) {
                System.out.println("MyStart -> updateDns -> 创建请求角色失败!");
                e.printStackTrace();
            }
        }
    }

    public static void updateDns() {

        // 1.获取本机 IPv6 地址
        ip = IPv6Address.getIp();
        System.out.println(ip);
        // 如果ip地址未变动,则不进行域名解析记录更新操作
        if (ipStack.pop().equals(ip))return;
        ipStack.push(ip);

        // 2.获取指定域名的解析记录
        DescribeDomainRecordsResponse recordsResponse = ResolutionDNS.domainRecords(DOMAIN_NAME,client);
        List<DescribeDomainRecordsResponseBody.DescribeDomainRecordsResponseBodyDomainRecordsRecord> record = recordsResponse.getBody().getDomainRecords().getRecord();

        // 如果当前不存在解析记录,就添加一个主机记录为 * ,类型为 "AAAA" 的解析记录;
        if (record.size()==0) {
            AddDomainRecordResponse response = ResolutionDNS.addDomainRecord(DOMAIN_NAME,"*","AAAA",ip,client);
            System.out.println(LocalDateTime.now().format(formatter)+"-> [ recordId : "+response.getBody().getRecordId()
                    +" | requestId : "+response.getBody().getRequestId());
        } else {
            // 3.遍历解析记录,并更新
            record.forEach(o->{
                // 只对IPv6的类型进行修改
                if (o.getType().equals("AAAA")){
                    try {
                        UpdateDomainRecordResponse updateResponse = ResolutionDNS.domainResolution(o.getRecordId(), o.getRR(), o.getType(), ip, client);
                        System.out.println(LocalDateTime.now().format(formatter)+"-> [ recordId : "+updateResponse.getBody().getRecordId()
                                +" | requestId : "+updateResponse.getBody().getRequestId());
                    } catch (TeaException e) {
                        System.out.println(LocalDateTime.now().format(formatter)+"调用阿里云接口异常,请于阿里云查看错误信息!");
                        e.printStackTrace();
                    }

                }
            });
        }
    }

    public static void main(String[] args) {
        System.out.println("已启动,请稍后......");
        ScheduledThreadPoolExecutor executor = (ScheduledThreadPoolExecutor) Executors.newScheduledThreadPool(2);
        // 创建一个定时任务,每隔一个小时执行一次
        executor.scheduleAtFixedRate(()-> {
            updateDns();
        }, 0,1, TimeUnit.HOURS);
    }
}
